<?php
namespace app\lib;

class Dingtalk
{

    protected $newDingTalkClientGet;
    protected $newDingTalkClientPost;
    private $api_url;
    private $CorpId;
    private $AgentId;
    private $AppKey;
    private $AppSecret;

    public $access_token_get_timestamp;

    public function __construct()
    {
        $this->api_url = DINGTALK_API_URL;
        $this->CorpId = DINGTALK_CORP_ID;
        $this->AgentId = DINGTALK_AGENT_ID;
        $this->AppKey = DINGTALK_APP_KEY;
        $this->AppSecret = DINGTALK_APP_SECRET;

        include "../extend/taobao/TopSdk.php";
        date_default_timezone_set('Asia/Shanghai');
        // DingTalkConstant::$METHOD_GET 要与下面调用接口url要求的保持一致
        $this->newDingTalkClientGet = new \DingTalkClient(\DingTalkConstant::$CALL_TYPE_OAPI, \DingTalkConstant::$METHOD_GET , \DingTalkConstant::$FORMAT_JSON);
        $this->newDingTalkClientPost = new \DingTalkClient(\DingTalkConstant::$CALL_TYPE_OAPI, \DingTalkConstant::$METHOD_POST , \DingTalkConstant::$FORMAT_JSON);
    }


    /**
     * @introduction:根据企业的AppKey和APPsecret获取access_token
     * @return \SimpleXMLElement|null
     * @author:cxh
     * @date: 2020/5/19 15:26
     */
    public function getAccessToken()
    {
        $req = new \OapiGettokenRequest();
        $req->setAppkey($this->AppKey);
        $req->setAppsecret($this->AppSecret);
        $resp = $this->newDingTalkClientGet->execute($req,  '', $this->api_url.'gettoken');
        if(property_exists($resp, 'errcode') && $resp->errcode == 0){
            return $resp->access_token;
        }else{
            return null;
        }
    }

    /**
     * @introduction:根据access_token和authCode获取当前登陆用户信息
     * @param null $access_token
     * @param null $authCode
     * @return mixed|\ResultSet|\SimpleXMLElement|null
     * @author:cxh
     * @date: 2020/5/19 15:48
     */
    public function getUserInfo($access_token = null ,$authCode = null){
        $req = new \OapiUserGetuserinfoRequest;
        $req->setCode($authCode);
        $resp = $this->newDingTalkClientGet->execute($req, $access_token, $this->api_url.'user/getuserinfo');
        if(property_exists($resp, 'errcode') && $resp->errcode == 0){
            return $resp;
        }else{
            return null;
        }
    }

    /**
     * @auther zlq
     * @create_time 2020/5/19 17:50
     * @description 查询用户详情
     * @param $dd_user_id 用户钉钉ID
     * @return array
     */
    public function getUserInfoByDDUserId($dd_user_id)
    {
        $request = new \OapiUserGetRequest();
        $request->setUserid($dd_user_id);
        $access_token = $this->getAccessToken();
        $response = $this->newDingTalkClientGet->execute($request, $access_token, $this->api_url.'user/get');
        if (!property_exists($response, 'errcode') || $response->errcode != 0) {
            return [];
        } else {
            return [
                'userid' => $response->userid,
                'unionid' => $response->unionid,
                'openId' => $response->openId,
                'name' => $response->name,
                'active' => $response->active,
                'isAdmin' => $response->isAdmin,
                'isHide' => $response->isHide,
                 'avatar' => $response->avatar,
                // 'isLeaderInDepts' => $response->isLeaderInDepts,
                // 'isBoss' => $response->isBoss,
                // 'isSenior' => $response->isSenior,
                // 'orderInDepts' => $response->orderInDepts,
                // 'mobile' => $response->mobile,
                //  'hiredDate' => $response->hiredDate,
                // 'jobnumber' => $response->jobnumber,
                // 'email' => $response->email,
                // 'workPlace' => $response->workPlace,
                // 'department' => implode(',', $response->department),
                // 'tel' => $response->tel,
                // 'remark' => $response->remark,
                // 'extattr' => json_encode($response->extattr),
                // 'stateCode' => $response->stateCode,
                // 'position' => $response->manager,
            ];
        }
    }


    /**
     * @auther zlq
     * @create_time 2020/5/19 17:37
     * @description 发送通知信息
     * @param $dd_user_id 用户ID，多个用英文逗号分隔(,)
     * @param $message 内容
     * @return \SimpleXMLElement
     */
    public function sendNoticeMessage($dd_user_id, $message)
    {
        $request = new \OapiMessageCorpconversationAsyncsendV2Request();
        $request->setAgentId($this->AgentId);
        $request->setUseridList($dd_user_id);
        $request->setToAllUser(false);
        $msg = ['msgtype' => 'text', 'text' => ['content' => $message]];
        $msg_json = json_encode($msg);
        $request->setMsg($msg_json);
        $access_token = $this->getAccessToken();
        $response = $this->newDingTalkClientGet->execute($request, $access_token, $this->api_url . "topapi/message/corpconversation/asyncsend_v2");
        $data = json_decode(json_encode($response),true);
        if (!isset($data['errcode']) || (isset($data['errcode']) && $data['errcode'] != 0)) {
            return $data['errcode'];
        } else {
            return -1;
        }
    }

    /**
     * @auther zlq
     * @create_time 2020/5/23 11:09
     * @description 获取所有部门列表
     * @param int $parent_id
     * @return array|mixed
     */
    public function getAllDeptList($parent_id = 1)
    {
        $request = new \OapiDepartmentListRequest();
        $access_token = $this->getAccessToken();
        $request->setId($parent_id);
        $response = $this->newDingTalkClientGet->execute($request, $access_token, $this->api_url . "department/list");
        $data = json_decode(json_encode($response),true);
        if (!isset($data['errcode']) || (isset($data['errcode']) && $data['errcode'] != 0)) {
            return [];
        } else {
            $data = json_decode(json_encode($response),true);
            return $data['department'];
        }
    }

    /**
     * @auther zlq
     * @create_time 2020/5/23 11:14
     * @description 获取部门用户列表
     * @param $dept_id
     * @return array|mixed
     */
    public function getDeptUserList($dept_id)
    {
        $request = new \OapiUserGetDeptMemberRequest();
        $request->setDeptId($dept_id);
        $access_token = $this->getAccessToken();
        $response = $this->newDingTalkClientGet->execute($request, $access_token, $this->api_url . "/user/getDeptMember");
        $data = json_decode(json_encode($response),true);
        if (!isset($data['errcode']) || (isset($data['errcode']) && $data['errcode'] != 0)) {
            return [];
        } else {
            return $data['userIds'];
        }
    }

    /**
     * @auther zlq
     * @create_time 2020/6/10 15:35
     * @description 获取某部门下子部门
     * @param $dept_id
     * @return array|mixed
     */
    public function getNextGradeDeptList($dept_id)
    {
        $req = new \OapiDepartmentListIdsRequest();
        $req->setId($dept_id);
        $access_token = $this->getAccessToken();
        $response = $this->newDingTalkClientGet->execute($req, $access_token, $this->api_url . "/department/list_ids");
        $data = json_decode(json_encode($response),true);
        if (!isset($data['errcode']) || (isset($data['errcode']) && $data['errcode'] != 0)) {
            return [];
        } else {
            return $data['sub_dept_id_list'];
        }
    }

    /*********************************20200606 添加回调相关接口 start****************************/


    /**
     * @auther zlq
     * @create_time 2020/6/6 9:56
     * @description 查询事假回调接口
     * @return array|mixed
     */
    public function getCallBack()
    {
        $req = new \OapiCallBackGetCallBackRequest();
        $access_token = $this->getAccessToken();
        $url = $this->api_url . "/call_back/get_call_back";
        $response = $this->newDingTalkClientGet->execute($req, $access_token, $url);
        $data = json_decode(json_encode($response),true);
        if (!isset($data['errcode']) || (isset($data['errcode']) && $data['errcode'] != 0)) {
            return [];
        } else {
            return $data;
        }
    }

    /**
     * @auther zlq
     * @create_time 2020/6/6 9:56
     * @description 获取回调失败结果
     * @return array|mixed
     */
    public function getCallBackFailedResult()
    {
        $req = new \OapiCallBackGetCallBackFailedResultRequest();
        $access_token = $this->getAccessToken();
        $url = $this->api_url . "/call_back/get_call_back_failed_result";
        $response = $this->newDingTalkClientGet->execute($req, $access_token, $url);
        $data = json_decode(json_encode($response),true);
        if (!isset($data['errcode']) || (isset($data['errcode']) && $data['errcode'] != 0)) {
            return [];
        } else {
            return $data;
        }
    }

    /* 需要监听的事件类型，有20种，
    “user_add_org”, “user_modify_org”, “user_leave_org”, “org_admin_add”,
    “org_admin_remove”, “org_dept_create”,
    “org_dept_modify”, “org_dept_remove”, “org_remove”,
    “chat_add_member”, “chat_remove_member”, “chat_quit”,
    “chat_update_owner”, “chat_update_title”, “chat_disband”,
    “chat_disband_microapp”, “check_in”, “bpms_task_change”,
    “bpms_instance_change”, “label_user_change”, “label_conf_add”,
    “label_conf_modify”, “label_conf_del”,
    *
     * @note 下面两个方法的参数相关
     * @param $call_back_tag 监听的事件类型,审批相关：“bpms_task_change”，“bpms_instance_change”,
     * bpms_task_change 审批任务开始，结束，转交,
     * bpms_instance_change 审批实例开始，结束
     * @param $token 加解密需要用到的token，ISV(服务提供商)推荐使用注册套件时填写的token，普通企业可以随机填写
     * @param $ase_key 数据加密密钥。用于回调数据的加密，长度固定为43个字符，从a-z, A-Z, 0-9共62个字符中选取,您可以随机生成
     * ISV(服务提供商)推荐使用注册套件时填写的EncodingAESKey
     * @url 接收事件回调的url，必须是公网可以访问的url地址
     */
    /**
     * @auther zlq
     * @create_time 2020/6/6 10:29
     * @description 注册回调借口
     * @return array|mixed
     */
    public function registerCallBack()
    {
        $req = new \OapiCallBackRegisterCallBackRequest();
        $access_token = $this->getAccessToken();
        $url = $this->api_url . "/call_back/register_call_back";
        $req->setAesKey(CALL_BACK_AES_KEY);
        $req->setToken(CALL_BACK_TOKEN);
        $req->setCallBackTag(CALL_BACK_TAG);
        $req->setUrl(CALL_BACK_URL);
        $response = $this->newDingTalkClientPost->execute($req, $access_token, $url);

        return ['code'=>$response->errcode , 'msg'=>$response->errmsg];
    }

    /**
     * @auther zlq
     * @create_time 2020/6/6 10:30
     * @description 更新之前的回调接口
     * @param $call_back_tag
     * @param $api_url
     * @return array|mixed
     */
    public function updateCallBack()
    {
        $req = new \OapiCallBackUpdateCallBackRequest;
        $access_token = $this->getAccessToken();
        $url = $this->api_url . "/call_back/update_call_back";
        $req->setAesKey(CALL_BACK_AES_KEY);
        $req->setToken(CALL_BACK_TOKEN);
        $req->setCallBackTag(CALL_BACK_TAG);
        $req->setUrl(CALL_BACK_URL);
        $response = $this->newDingTalkClientPost->execute($req, $access_token, $url);

        return ['code'=>$response->errcode , 'msg'=>$response->errmsg];

    }


    /**
     * @auther zlq
     * @create_time 2020/6/6 9:56
     * @description 删除回调请求
     * @return array|mixed
     */
    public function deleteCallBack()
    {
        $req = new \OapiCallBackDeleteCallBackRequest();
        $access_token = $this->getAccessToken();
        $url = $this->api_url . "/call_back/delete_call_back";
        $response = $this->newDingTalkClientGet->execute($req, $access_token, $url);

        return ['code'=>$response->errcode , 'msg'=>$response->errmsg];
    }


    /**
     * @auther zlq
     * @create_time 2020/6/6 11:11
     * @description 获取对应长度字符串
     * @param $length
     * @return false|string
     */
    public function getAesKeyTemp($length)
    {
        $chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
        $mix = str_shuffle($chars);
        return substr($mix, 0, $length);
    }
    /*********************************20200606 添加回调相关接口   end****************************/

}